package parcebibletext;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



/**
 *Breaks down the Bile text into parts as requiered.
 * @author Shavy Yarmush
 **/ 
public class Parcer 
{
    private List<String> args;
    
    final static List<String> VALID_ARGS = Arrays.asList("removeVerseHeader","verseHeaderInLine","removeNekudot","removePandS","removeChars","removeHebChars");
    final static List<String> FIRST_ARG = Arrays.asList("verse","phrase","word");
    final static List<String> SECOND_ARG = Arrays.asList("-0","-1","-2","-3","-4","-5");
    
    //helper fields
    final static String newLine = "" + (char)UNICODE.CARRIAGE_RETURN + (char)UNICODE.LINE_FEED;
    final static String petucha = "" + (char)UNICODE.BRACE_OPEN + (char)UNICODE.LETTER_PAY +  (char)UNICODE.BRACE_CLOSE ;
    final static String Setumah = "" + (char)UNICODE.BRACE_OPEN + (char)UNICODE.LETTER_SAMECH +  (char)UNICODE.BRACE_CLOSE ;
    
    /**
     * Breaks down given Bible text according to the instructions of the args.
     * @param args The arguments instructing how to break down the text.
     */
    public Parcer(String[] args)
    {
        validateArgs(args);
        
        this.args = Arrays.asList(args);
    }

    public String convertText(String bibleText) 
    {
        bibleText  = cleanText(bibleText);
        
        bibleText = bibleText.substring( bibleText.indexOf(UNICODE.COMMA_CHAR)-1);//get rid of book name from text
        bibleText = bibleText.replace("--", "!");//place holder for phrase
        bibleText = bibleText.replace("-", " ");
        
        switch (getArgs().get(0))
        {
            case ARGS.FA_WORD:
                bibleText = bibleText.replace(" ", "" + newLine);
                break;
            case ARGS.FA_PHRASE:
                bibleText = bibleText.replace(",", "," + newLine);
                bibleText = bibleText.replace(";", ";" + newLine);
                bibleText = bibleText.replace(":", ":" + newLine);
                bibleText = bibleText.replace("!", "--" + newLine);
            case ARGS.FA_VERSE:
               bibleText = bibleText.replace(".", "." + newLine); 
                break;
            default:
                throw new RuntimeException("AAAAHHHHH"); 
        }
        
        bibleText = processPandS(bibleText,getArgs().contains( ARGS.OA_REMOVE_P_AND_S));
        
        bibleText = processVerseHeader(bibleText, getArgs().contains(ARGS.OA_REMOVE_VERSE_HEADER),getArgs().contains(ARGS.OA_VERSE_HEADER_IN_LINE));
        
        if (getArgs().contains(ARGS.OA_REMOVE_CHARS)) 
            bibleText = removeChars(bibleText);
        
        if (getArgs().contains(ARGS.OA_REMOVE_NEKUDOT)) 
            bibleText = removeNekudot(bibleText);
        
        if (getArgs().contains(ARGS.OA_REMOVE_HEB_CHARS)) 
            bibleText = removeHebrewChars(bibleText);
        
        return cleanText(bibleText);
    }
    
    static void validateTextFile(String string) 
    {
        
    }
    
    String cleanText(String bibleText)
    {
        while(bibleText.contains("  ") || bibleText.contains(" " + newLine) || 
                bibleText.contains(newLine + " ") || bibleText.contains(newLine + newLine))
        {
            bibleText  = bibleText.replace("  ", " ");
            bibleText  = bibleText.replace(" " + newLine, newLine);
            bibleText  = bibleText.replace(newLine + " ", newLine);
            bibleText  = bibleText.replace(newLine + newLine, newLine);
        }
        
        return bibleText;
    }

    String listOfValidArgs() 
    {
        String validArgs = "Choose one for the first argument: ";
        
        for(String arg : FIRST_ARG)
            validArgs += arg +  ", ";
        
        validArgs += " and any of the following options are optional: ";
                
        for(String arg : VALID_ARGS)
            validArgs += arg +  ", ";
        
        return validArgs;
    }

    void validateArgs(String[] args) 
    {
        if(args.length == 0)
            throw new IllegalArgumentException("The first argunment is mandatory, but it's missing.  Valid arguments are: " + listOfValidArgs());
        
        for(String arg : args)
            if(!VALID_ARGS.contains(arg) && !FIRST_ARG.contains(arg))
                throw new IllegalArgumentException("One or more of the arguments pased into the program are not valid. Valid arguments are: " + listOfValidArgs());
        
        if(!FIRST_ARG.contains(args[0]))
            throw new IllegalArgumentException("The first argunmet was invalid. here are valid arguments: " + listOfValidArgs());
    }

    static String argsToString(List<String> args)
    {
        String validArgs = "_";
       
        for(String arg : args)
            validArgs += arg + "_";
        
        return validArgs.substring(0,validArgs.length()-1);
    }

    String processPandS(String bibleText, boolean contains) 
    {
        
        if(contains)
        {
            bibleText = bibleText.replace(petucha, ""); 
            bibleText = bibleText.replace(Setumah, "");
        }
        else
        {
            bibleText = bibleText.replace(petucha , petucha +  newLine); 
            bibleText = bibleText.replace(Setumah , Setumah +  newLine); 
        }
        
        return bibleText; 
    }

    String removeChars(String bibleText) 
    {
        bibleText = bibleText.replace("," + newLine , newLine );
        bibleText = bibleText.replace(";", "" );
        bibleText = bibleText.replace(":", "");
        bibleText = bibleText.replace(".", ""); 
        
        return bibleText; 
    }

    String removeNekudot(String bibleText) 
    {
        return bibleText.replaceAll("[\\u05B0-\\u05C2]", "");
    }

    String processVerseHeader(String bibleText, boolean removeVerseHeader, boolean verseHeaderInLine) 
    {
        Matcher match = Pattern.compile ("[\\u05D0-\\u05EA]{1,3}(,[\\u05D0-\\u05EA]{1,3}){1,2}").matcher(bibleText);
        
        if (removeVerseHeader)
        {
            while(match.find())
            {
                String sss = match.group();
                bibleText = bibleText.replace(sss, "");
            } 
        }
        else if (verseHeaderInLine)
        {
            if(true)
            {}
        }
        else
        {
            while(match.find())
            {
                String sss = match.group();
                bibleText = bibleText.replace(sss, sss + newLine);
            } 
        }
        
        
        return bibleText;
    }

    /**
     * @return the args
     */
    public List<String> getArgs() 
    {
        return new ArrayList(args);
    }

    /**
     * @param args the args to set
     */
    public void setArgs(List<String> args) 
    {
        this.args = args;
    }

    private String removeHebrewChars(String bibleText) 
    {
        bibleText = bibleText.replaceAll("[\\u0590-\\u05AF]", "");
        bibleText = bibleText.replaceAll("[\\u05C3-\\u05CF]", "");
        bibleText = bibleText.replaceAll("[\\u05EB-\\u05FF]", "");
        
        return bibleText;
    }
}
class UNICODE
{
    final static int ALEF_BEIS_FIRST    = 0x05D0;
    final static int ALEF_BEIS_LAST     = 0x05EA;
    final static int NEKUDOT_FIRST      = 0x05B0;
    final static int NEKUDOT_LAST       = 0x05C2;
    final static int SPACE_CHAR         = 0x20;
    final static int COMMA_CHAR         = 0x2c;
    final static int HYPHEN_CHAR        = 0x2d;
    final static int PERIOD_CHAR        = 0x2e;
    final static int BRACE_OPEN         = 0x7b;
    final static int BRACE_CLOSE        = 0x7d;
    final static int SEMICOLON_CHAR     = 0x3b;
    final static int COLON_CHAR         = 0x3a;
    final static int LINE_FEED          = 0xa;
    final static int CARRIAGE_RETURN    = 0xd;
    final static int LETTER_PAY         = 0x05E4;
    final static int LETTER_SAMECH      = 0x05E1;
    final static int HEBREW_CHARS_FIRST = 0x0590;
    final static int HEBREW_CHARS_LAST  = 0x05FF;
}

class ARGS
{
    final static String FA_VERSE    = "verse";
    final static String FA_PHRASE   = "phrase";
    final static String FA_WORD     = "word";
    
    final static String OA_REMOVE_VERSE_HEADER  = "removeVerseHeader";
    final static String OA_VERSE_HEADER_IN_LINE = "verseHeaderInLine";
    final static String OA_REMOVE_NEKUDOT       = "removeNekudot";
    final static String OA_REMOVE_P_AND_S       = "removePandS";
    final static String OA_REMOVE_CHARS         = "removeChars";
    final static String OA_REMOVE_HEB_CHARS     = "removeHebChars";
}


